package routes

import (
	"net/http"
	"path/filepath"
	"time"

	"github.com/gin-gonic/gin"

	"github.com/samaa/photosalesplus/backend/internal/handlers"
	"github.com/samaa/photosalesplus/backend/internal/middleware"
)

type Dependencies struct {
	AuthHandler            *handlers.AuthHandler
	MerchantAuthHandler    *handlers.MerchantAuthHandler
	ProductHandler         *handlers.ProductHandler
	OrderHandler           *handlers.OrderHandler
	UploadHandler          *handlers.UploadHandler
	AssetHandler           *handlers.AssetHandler
	AuthMiddleware         *middleware.AuthMiddleware
	MerchantAuthMiddleware *middleware.MerchantAuthMiddleware
	StorageDir             string
}

func Register(r *gin.Engine, deps Dependencies) {
	r.GET("/health", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{"status": "ok"})
	})

	// Static images with long cache headers
	images := r.Group("/images")
	images.Use(func(c *gin.Context) {
		// one year
		c.Header("Cache-Control", "public, max-age=31536000, immutable")
		// Optional: strong caching can be combined with last-modified/etag by underlying server
		// Add an explicit Expires for some old proxies
		expires := time.Now().Add(365 * 24 * time.Hour).UTC().Format(http.TimeFormat)
		c.Header("Expires", expires)
		c.Next()
	})
	// Only expose preview derivatives; originals are not publicly accessible
	images.Static("/preview", filepath.Join(deps.StorageDir, "preview"))

	api := r.Group("/api/v1")

	api.POST("/auth/register", deps.AuthHandler.Register)
	api.POST("/auth/login", deps.AuthHandler.Login)
	api.POST("/merchant/login", deps.MerchantAuthHandler.Login)

	api.GET("/products", deps.ProductHandler.List)
	api.GET("/products/:id", deps.ProductHandler.Get)
	api.GET("/assets/:id/original", deps.AssetHandler.GetOriginal)
	api.GET("/leaderboard/users", deps.OrderHandler.CustomerLeaderboard)

	protected := api.Group("")
	protected.Use(deps.AuthMiddleware.Handle)
	{
		// common for all logged-in users
		protected.POST("/auth/logout", deps.AuthHandler.Logout)
		protected.DELETE("/auth/account", deps.AuthHandler.DeleteAccount)
		protected.PATCH("/profile", deps.AuthHandler.UpdateProfile)
		protected.POST("/profile/avatar/upload", deps.UploadHandler.UploadAvatar)
		protected.POST("/orders/preview", deps.OrderHandler.Preview)
		protected.POST("/orders", deps.OrderHandler.Create)
		protected.GET("/orders", deps.OrderHandler.List)
		protected.GET("/purchases", deps.OrderHandler.Purchases)
	}

	// merchant-only endpoints require merchant token
	merchant := api.Group("")
	if deps.MerchantAuthMiddleware != nil {
		merchant.Use(deps.MerchantAuthMiddleware.Handle)
	}
	merchant.POST("/products", deps.ProductHandler.Create)
	merchant.PUT("/products/:id", deps.ProductHandler.Update)
	merchant.PATCH("/products/:id/publish", deps.ProductHandler.UpdatePublishStatus)
	merchant.DELETE("/products/:id", deps.ProductHandler.Delete)
	merchant.GET("/merchant/overview", deps.OrderHandler.Overview)
	merchant.POST("/uploads/images", deps.UploadHandler.UploadImage)
}
